home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AMIGA-CD 2
/
Amiga-CD - Volume 2.iso
/
gepackte_disketten
/
1994
/
08_94_5.dms
/
08_94_5.adf
/
term-4.0-Source.lha
/
termMain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-14
|
89KB
|
4,769 lines
/*
** termMain.c
**
** Program main routines and event loop
**
** Copyright © 1990-1994 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
#include "termEmulationProcess.h"
/* Argument vectors offsets. */
enum { ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,
ARG_COUNT
};
/* Argument template. */
#define ARGTEMPLATE "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S"
/* Local config path variable. */
STATIC STRPTR ConfigPath;
STATIC UBYTE __far ThePath[MAX_FILENAME_LENGTH];
/* Local dialing list. */
STATIC struct List *LocalDialList;
STATIC LONG LocalCount = -1;
/* Startup file name. */
STATIC UBYTE __far StartupFile[MAX_FILENAME_LENGTH];
/* Segment split routine, has to be local. */
STATIC struct Process * __regargs SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
STATIC VOID CloseLibs(VOID);
/* main():
*
* This is our main entry point, check for the right
* Kickstart version and fire off the background task
* if approritate.
*/
LONG
main()
{
STRPTR Result;
/* Are we running as a child of Workbench? */
ThisProcess = (struct Process *)SysBase -> ThisTask;
if(!ThisProcess -> pr_CLI)
{
WaitPort(&ThisProcess -> pr_MsgPort);
WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
}
else
WBenchMsg = NULL;
/* Now try to open dos.library and utility.library and go on examining
* our calling parameters.
*/
if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
{
CloseLibs();
return(RETURN_FAIL);
}
if(!(UtilityBase = OpenLibrary("utility.library",0)))
{
CloseLibs();
return(RETURN_FAIL);
}
/* We were called from Shell. */
if(ThisProcess -> pr_CLI)
{
STRPTR *ArgArray;
/* Use the cute ReadArgs parser, allocate the
* argument vectors...
*/
if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
{
struct RDArgs *ArgsPtr;
if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
{
ArgsPtr -> RDA_ExtHelp = "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
" [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
" [NEW] [SYNC] [QUIET] [BEHIND]\n\n"
" Window = Output window specifier\n"
" PubScreen = Name of public screen to open window upon\n"
" Startup = ARexx script file to run on startup\n"
" Settings = Main configuration file name or path name to search for it\n"
" Unit = Serial device driver unit number\n"
" Device = Serial device driver name\n"
" New = Spawn a new `term' process\n"
" Sync = Keep links to Shell environment\n"
" Quiet = Start iconified\n"
" Behind = Open screen behind all other screens, don't activate the window\n\n";
/* Parse the args (if any). */
if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
{
/* Pop a running `term' to the front? */
if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
{
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
{
if(TermPort -> TopWindow)
BumpWindow(TermPort -> TopWindow);
}
TermPort = NULL;
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseLibs();
return(RETURN_OK);
}
if(ArgArray[ARG_DEBUG])
DebugFlag = TRUE;
/* Are we to use a special settings path? */
if(ArgArray[ARG_SETTINGS])
{
ConfigPath = ThePath;
strcpy(ThePath,ArgArray[ARG_SETTINGS]);
}
/* Are we to use a special ARexx host port name? */
if(ArgArray[ARG_PORTNAME])
strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
/* Are we to use a special output window name? */
if(ArgArray[ARG_WINDOW])
strcpy(WindowName,ArgArray[ARG_WINDOW]);
/* Are we to run an ARexx script on startup? */
if(ArgArray[ARG_STARTUP])
strcpy(StartupFile,ArgArray[ARG_STARTUP]);
/* Are we to open a window on a public screen? */
if(ArgArray[ARG_PUBSCREEN])
strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
/* Are we to use a special device? */
if(ArgArray[ARG_DEVICE])
{
strcpy(NewDevice,ArgArray[ARG_DEVICE]);
UseNewDevice = TRUE;
}
/* Are we to use a special unit number? */
if(ArgArray[ARG_UNIT])
{
NewUnit = *(LONG *)ArgArray[ARG_UNIT];
UseNewUnit = TRUE;
}
/* Are we to start up iconified? */
if(ArgArray[ARG_QUIET])
{
if(!StartupFile[0])
DoIconify = TRUE;
}
/* Hide the screen and don't activate the window? */
if(ArgArray[ARG_BEHIND])
KeepQuiet = TRUE;
/* We are to keep our links to
* the Shell.
*/
if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
{
BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
/* Do we have enough stack space available? */
if(((struct CommandLineInterface *)BADDR(ThisProcess -> pr_CLI)) -> cli_DefaultStack < 4096)
{
Printf("\33[1mterm:\33[0m %s.\a\n","Sorry, the Shell stack must be at least 16384 bytes large");
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseLibs();
return(RETURN_FAIL);
}
/* Open our resources and
* squeak on failure.
*/
if(Result = OpenAll(ConfigPath))
{
if(Result[0])
Printf("\33[1mterm:\33[0m %s!\a\n",Result);
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseAll(TRUE);
return(RETURN_FAIL);
}
/* Go into main input
* loop.
*/
HandleInput();
/* Free the argument
* data.
*/
FreeArgs(ArgsPtr);
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
/* Restore old priority. */
SetTaskPri(ThisProcess,(LONG)OldPri);
/* Terminate execution. */
CloseAll(TRUE);
return(RETURN_OK);
}
FreeArgs(ArgsPtr);
}
else
{
PrintFault(IoErr(),"term");
FreeDosObject(DOS_RDARGS,ArgsPtr);
FreeVec(ArgArray);
CloseLibs();
return(RETURN_ERROR);
}
FreeDosObject(DOS_RDARGS,ArgsPtr);
}
FreeVec(ArgArray);
/* Create a new process from our code. */
if(!SegmentSplit("term main process",0,16384,HandleInput))
{
Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
CloseLibs();
return(RETURN_FAIL);
}
}
else
{
Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
CloseLibs();
return(RETURN_FAIL);
}
}
else
{
LONG StackSize;
StackSize = (LONG)SysBase -> ThisTask -> tc_SPUpper - (LONG)SysBase -> ThisTask -> tc_SPLower;
if(StackSize < 16384)
{
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
MyEasyRequest(NULL,"`term' has a problem:\nThe current stack size of %ld bytes is too low,\nplease edit the tool icon to use at least\n16384 bytes and restart the program.","Continue",StackSize);
CloseLibs();
return(RETURN_FAIL);
}
else
{
WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
/* Open icon.library, we want to take a
* look at the icon.
*/
if(IconBase = OpenLibrary("icon.library",0))
{
struct DiskObject *Icon;
/* Try to read the icon file. */
if(Icon = GetProgramIcon())
{
STRPTR Type;
if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
DebugFlag = TRUE;
/* Look for a `Settings' tooltype. */
if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
{
/* Remember the path and continue. */
strcpy(ThePath,ConfigPath);
ConfigPath = ThePath;
}
/* Look for a `Portname' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
strcpy(RexxPortName,Type);
else
RexxPortName[0] = 0;
/* Look for a `Window' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
strcpy(WindowName,Type);
else
WindowName[0] = 0;
/* Look for a `Pubscreen' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
strcpy(SomePubScreenName,Type);
else
SomePubScreenName[0] = 0;
/* Look for a `Startup' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
strcpy(StartupFile,Type);
else
StartupFile[0] = 0;
/* Look for a `Device' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
{
if(Type[0])
{
strcpy(NewDevice,Type);
UseNewDevice = TRUE;
}
}
/* Look for a `Unit' tooltype. */
if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
{
if(Type[0])
{
NewUnit = Atol(Type);
UseNewUnit = TRUE;
}
}
/* Look for a `Quiet' tooltype. */
if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
{
if(!StartupFile[0])
DoIconify = TRUE;
}
/* Look for a `Behind' tooltype. */
if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
KeepQuiet = TRUE;
/* Free the icon. */
FreeDiskObject(Icon);
}
CloseLibrary(IconBase);
IconBase = NULL;
}
/* Initialize this, so OpenAll will work with
* correct data.
*/
TermPort = (struct TermPort *)FindPort("term Port");
/* We were called from Workbench. */
if(Result = OpenAll(ConfigPath))
{
if(IntuitionBase && Result[0])
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
CloseAll(TRUE);
}
else
HandleInput();
}
}
return(RETURN_OK);
}
/* CloseLibs():
*
* Plain and simple: close two libraries and clean up.
*/
STATIC VOID
CloseLibs(VOID)
{
if(UtilityBase)
{
CloseLibrary(UtilityBase);
UtilityBase = NULL;
}
if(WBenchMsg)
CurrentDir(WBenchLock);
if(DOSBase)
{
CloseLibrary(DOSBase);
DOSBase = NULL;
}
#ifdef BETA
StopBetaTask();
#endif /* BETA */
if(WBenchMsg)
{
Forbid();
ReplyMsg((struct Message *)WBenchMsg);
}
}
/* ProcessCleanup(register __d1 BPTR SegList):
*
* Frees all resource the main process has allocated when
* it exits.
*/
STATIC VOID __saveds __asm
ProcessCleanup(register __d1 BPTR SegList)
{
CloseAll(FALSE);
Forbid();
UnLoadSeg(SegList);
CloseLibrary(DOSBase);
DOSBase = NULL;
}
/* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
*
* Create a new process from the current one.
*/
STATIC struct Process * __regargs
SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
{
struct Process *Child;
struct CommandLineInterface *CLI;
CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
Forbid();
Child = CreateNewProcTags(
NP_CommandName, "term",
NP_Name, Name,
NP_Priority, Pri,
NP_StackSize, StackSize,
NP_Entry, Function,
NP_Cli, TRUE,
NP_ExitCode, ProcessCleanup,
NP_ExitData, CLI -> cli_Module,
TAG_DONE);
if(Child)
CLI -> cli_Module = NULL;
Permit();
return(Child);
}
/* HandleInput():
*
* This is our main input loop (check window & serial).
*/
VOID __saveds
HandleInput()
{
STRPTR Error;
BOOLEAN AlmostFinished = FALSE;
ThisProcess = (struct Process *)SysBase -> ThisTask;
/* Open the resources we need. */
if(!IntuitionBase)
{
STRPTR Result;
if(Result = OpenAll(ConfigPath))
{
if(IntuitionBase && Result[0])
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
if(WBenchMsg)
CloseAll(TRUE);
return;
}
}
if(DoIconify)
{
HandleIconify();
DoIconify = FALSE;
if(MainTerminated)
goto Stop;
}
#ifndef BETA
if(!KeepQuiet)
BumpWindow(Window);
#endif /* BETA */
/* Set up the public screen data. */
PubScreenStuff();
/* Change program priority. */
SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
BlockWindows();
/* Load the phone book. */
LoadPhonebook(LastPhone);
/* Build new menu strip. */
if(Error = BuildMenu())
{
if(IntuitionBase)
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
CloseAll(TRUE);
return;
}
#ifdef BETA
StopBetaTask();
if(!KeepQuiet)
BumpWindow(Window);
#endif /* BETA */
/* Show our business card. */
if(!StartupFile[0] && !KeepQuiet)
{
if(ShowAbout(TRUE))
while(HandleRexx());
}
ReleaseWindows();
/* Don't do anything silly. */
KeepQuiet = FALSE;
/* Initialize the modem. */
SerialCommand(Config -> ModemConfig -> ModemInit);
/* Execute the startup macro (if any). */
if(Config -> CommandConfig -> StartupMacro[0])
SerialCommand(Config -> CommandConfig -> StartupMacro);
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
/* Go into input loop... */
Loop: while(!MainTerminated)
{
if(Recording)
{
if(RecordingLine)
Status = STATUS_RECORDING_LINE;
else
Status = STATUS_RECORDING;
}
/* Handle the signal responses. */
HandleResponse();
if(RebuildMenu)
{
if(Error = BuildMenu())
{
if(IntuitionBase)
MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
MainTerminated = TRUE;
break;
}
RebuildMenu = FALSE;
}
/* Are we to run an ARexx script file? */
if(StartupFile[0])
{
BlockWindows();
SendARexxCommand(StartupFile);
ReleaseWindows();
StartupFile[0] = 0;
}
/* Are we to leave the main loop? */
if(MainTerminated)
break;
/* Make the user notice not too obvious events. */
if(FlowInfo . Changed)
HandleFlowChange();
/* Are we no longer online? */
if(!Online && WasOnline)
HandleOnlineCleanup();
/* Now for public screen mode changes. */
if(FixPubScreenMode)
PubScreenStuff();
/* Now for window size changes. */
if(FixScreenSize)
ScreenSizeStuff();
/* Somebody told us to re-open the display
* (changed the terminal emulation/colour
* mode, etc.).
*/
if(ResetDisplay)
{
if(!DisplayReset())
break;
}
/* Display the online cost. */
if(!Online && CurrentPay)
{
/* Reset the text rendering styles, font, etc. in
* order to keep the following text from getting
* illegible.
*/
SoftReset();
/* Display how much we expect
* the user will have to pay for
* this call.
*/
ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
CurrentPay = 0;
}
/* Iconify the program? */
if(DoIconify)
{
HandleIconify();
if(MainTerminated)
break;
}
/* Reset the serial driver? */
if(ResetSerial)
{
HandleSerialReset();
if(MainTerminated)
break;
}
/* We are to release the serial.device (or
* whatever we are using) for some reason.
*/
if(ReleaseSerial)
{
HandleSerialRelease();
if(MainTerminated)
break;
}
/* Invoke the dialing function? */
if(DoDial != DIAL_IGNORE)
{
if(Online)
{
FreeDialList(FALSE);
DoDial = DIAL_IGNORE;
Forbid();
if(DialMsg)
{
DialMsg -> rm_Result1 = RC_WARN;
DialMsg -> rm_Result2 = 0;
ReplyMsg(DialMsg);
DialMsg = NULL;
}
Permit();
}
else
{
if(DoDial == DIAL_LIST)
{
BYTE OldStatus = Status;
DoDial = DIAL_IGNORE;
BlockWindows();
DialPanel();
FreeDialList(FALSE);
Status = OldStatus;
SetRedialMenu();
ReleaseWindows();
}
else
{
DoDial = DIAL_IGNORE;
HandleMenuCode(MEN_REDIAL,NULL);
}
}
}
/* Can we quit now? */
if(AlmostFinished && !CantQuit)
break;
}
/* Don't exit until all background processes
* have terminated.
*/
if(MainTerminated && CantQuit)
{
MainTerminated = FALSE;
AlmostFinished = TRUE;
goto Loop;
}
AlmostFinished = FALSE;
/* User wants to quit term, so let's try to close
* our magnificient screen and exit.
*/
Stop: if(Screen)
{
struct List *PubScreenList;
struct PubScreenNode *ScreenNode;
/* Lock the list of public screens. */
PubScreenList = LockPubScreenList();
/* Scan the list and try to find our
* private node.
*/
for(ScreenNode = (struct PubScreenNode *)PubScreenList -> lh_Head ; ScreenNode -> psn_Node . ln_Succ ; ScreenNode = (struct PubScreenNode *)ScreenNode -> psn_Node . ln_Succ)
{
if(ScreenNode -> psn_Screen == Screen)
break;
}
if(ScreenNode)
{
/* Okay, we know who and where we are,
* check the number of visitor windows
* currently open on our screen.
*/
if(ScreenNode -> psn_VisitorCount)
{
/* No chance, don't close
* the screen now.
*/
UnlockPubScreenList();
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
ReleaseWindows();
AlmostFinished = MainTerminated = FALSE;
goto Loop;
}
}
UnlockPubScreenList();
}
/* Send the modem exit command, shut down the
* serial.device and close all resources.
*/
SerialCommand(Config -> ModemConfig -> ModemExit);
ClearSerial();
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
if(Phonebook && PhoneSize)
DeletePhonebook(Phonebook,PhoneSize,TRUE);
if(!ThisProcess -> pr_CLI)
CloseAll(TRUE);
}
/* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell):
*
* Transmit text the user typed or pasted via the
* clipboard.
*/
STATIC VOID __regargs
SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell)
{
UBYTE Mask,c;
if(Config -> SerialConfig -> StripBit8)
Mask = 0x7F;
else
Mask = 0xFF;
while(Len--)
{
switch(CharType[c = (*Buffer++) & Mask])
{
case CHAR_ENTER:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
switch(Config -> TerminalConfig -> SendLF)
{
case LF_ASLF:
SerWrite("\n",1);
break;
case LF_ASLFCR:
SerWrite("\n\r",2);
break;
}
}
break;
case CHAR_RETURN:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
switch(Config -> TerminalConfig -> SendCR)
{
case CR_ASCR:
SerWrite("\r",1);
break;
case CR_ASCRLF:
SerWrite("\r\n",2);
break;
}
}
break;
/* Stop in/output. */
case CHAR_XON:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
if(Config -> SerialConfig -> xONxOFF)
Status = STATUS_HOLDING;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
}
break;
/* Restart in/output. */
case CHAR_XOFF:
if(Status == STATUS_HOLDING)
Status = STATUS_READY;
if(Config -> SerialConfig -> PassThrough)
SerWrite(&c,1);
break;
/* Any other character. */
case CHAR_VANILLA:
if(Status == STATUS_HOLDING)
{
if(Bell)
BellSignal();
}
else
{
if(Config -> TerminalConfig -> FontMode == FONT_IBM)
{
/* Convert special
* Amiga characters into
* alien IBM dialect.
*/
if(IBMConversion[c])
SerWrite(&IBMConversion[c],1);
else
SerWrite(&c,1);
}
else
SerWrite(&c,1);
}
break;
}
}
}
/* HandleWindow():
*
* This funny part checks the window(s) for incoming
* user input. Menus are handled elsewhere.
*/
BYTE
HandleWindow()
{
STATIC ULONG LastSeconds,LastMicros;
struct IntuiMessage *Message;
ULONG IClass,Code,Qualifier,Seconds,Micros;
LONG MouseX,MouseY,Len,GadgetID;
struct Gadget *Gadget;
UBYTE Char,InputBuffer[257];
struct Window *IDCMPWindow;
BOOLEAN Result = FALSE,ClickAndActivate = FALSE;
/* Are we reading input from the clipboard? */
if(ClipInput)
{
WORD Len = GetClip(InputBuffer,256,FALSE);
if(Len < 0)
{
CloseClip();
ClipInput = FALSE;
if(ClipXerox)
{
if(Config -> ClipConfig -> InsertSuffix[0])
SerialCommand(Config -> ClipConfig -> InsertSuffix);
ClipXerox = FALSE;
}
ClipPrefix = FALSE;
}
else
{
if(!ClipPrefix && ClipXerox)
{
if(Config -> ClipConfig -> InsertPrefix[0])
SerialCommand(Config -> ClipConfig -> InsertPrefix);
ClipPrefix = TRUE;
}
if(Len > 0)
SendInputTextBuffer(InputBuffer,Len,FALSE);
Result = TRUE;
}
}
/* Any news in the mail? */
if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
/* A click into the window should activate it, but
* we don't want to have the character snapping activated
* under these conditions. In this case we rely upon
* Intuition sending the IDCMP_ACTIVEWINDOW and
* IDCMP_MOUSEBUTTONS event marked with the same
* creation time stamp. Even if the Intuition
* implementation should change no harm should
* be done.
*/
Seconds = Message -> Seconds;
Micros = Message -> Micros;
if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
{
if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
ClickAndActivate = TRUE;
}
LastSeconds = Seconds;
LastMicros = Micros;
/* Pick up the pieces. */
IClass = Message -> Class;
Code = Message -> Code;
Qualifier = Message -> Qualifier;
Gadget = (struct Gadget *)Message -> IAddress;
MouseX = Message -> MouseX;
MouseY = Message -> MouseY;
IDCMPWindow = Message -> IDCMPWindow;
if(IClass == IDCMP_IDCMPUPDATE)
GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
if(IClass == IDCMP_RAWKEY)
{
/* Perform key conversion. */
if(XEmulatorBase)
{
if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
Char = InputBuffer[0];
}
else
Char = KeyConvert(Message,InputBuffer,&Len);
}
ReplyMsg(Message);
}
else
IClass = NULL;
/* Did we get any information? */
if(IClass)
{
/* The following messages probably
* originated from the fast! macro
* panel.
*/
if(IDCMPWindow == FastWindow)
{
switch(IClass)
{
/* Close the window. */
case IDCMP_CLOSEWINDOW:
CloseFastWindow();
return(TRUE);
/* Window size has changed for some reason. */
case IDCMP_NEWSIZE:
RefreshFastWindow(FALSE);
return(TRUE);
/* Some gadget was invoked. */
case IDCMP_GADGETUP:
case IDCMP_GADGETDOWN:
GadgetID = Gadget -> GadgetID;
case IDCMP_MOUSEMOVE:
case IDCMP_IDCMPUPDATE:
HandleFastWindowGadget(IClass,Code,GadgetID);
return(TRUE);
}
}
/* Status window activated? */
if(IDCMPWindow == StatusWindow)
{
if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
NormalCursor();
if(IClass == IDCMP_CLOSEWINDOW)
{
Forbid();
ClrSignal(SIG_HANDSHAKE);
Signal(StatusProcess,SIG_CLOSEWINDOW);
Wait(SIG_HANDSHAKE);
Permit();
ClearMenuStrip(StatusWindow);
CloseWindowSafely(StatusWindow);
StatusWindow = NULL;
}
}
/* Main window message? */
if(IDCMPWindow == Window)
{
switch(IClass)
{
case IDCMP_INACTIVEWINDOW:
HoldClick = FALSE;
GhostCursor();
break;
case IDCMP_ACTIVEWINDOW:
NormalCursor();
break;
case IDCMP_NEWSIZE:
/* Is a window clipping region installed? */
if(ClipRegion)
{
struct Rectangle RegionRectangle;
/* Install old region. */
InstallClipRegion(Window -> WLayer,OldRegion);
/* Fill in the clipping rectangle. */
RegionRectangle . MinX = Window -> BorderLeft;
RegionRectangle . MinY = Window -> BorderTop;
RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
/* Clear previous clipping region. */
ClearRegion(ClipRegion);
/* Set new clipping region. */
OrRectRegion(ClipRegion,&RegionRectangle);
/* Install new clipping region. */
OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
}
HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
break;
case IDCMP_CLOSEWINDOW:
HandleMenuCode(MEN_QUIT,Qualifier);
break;
case IDCMP_MOUSEMOVE:
if(HoldClick)
{
if(!Marking)
SetMarker(ClickX,ClickY);
else
{
MouseX -= WindowLeft;
if(MouseX < 0)
MouseX = 0;
if(MouseX > WindowWidth - 1)
MouseX = WindowWidth - 1;
MouseY -= WindowTop;
if(MouseY < 0)
MouseY = 0;
if(MouseY > WindowHeight - 1)
MouseY = WindowHeight - 1;
MoveMarker(MouseX,MouseY);
}
}
break;
case IDCMP_MOUSEBUTTONS:
if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
{
if(Code == SELECTUP)
HoldClick = FALSE;
if(Code == SELECTDOWN)
{
MouseX -= WindowLeft;
if(MouseX < 0)
MouseX = 0;
if(MouseX > WindowWidth - 1)
MouseX = WindowWidth - 1;
MouseY -= WindowTop;
if(MouseY < 0)
MouseY = 0;
if(MouseY > WindowHeight - 1)
MouseY = WindowHeight - 1;
HoldClick = TRUE;
if(Qualifier & IEQUALIFIER_CONTROL)
{
WORD FirstX,FirstY;
FirstX = MouseX / TextFontWidth;
FirstY = MouseY / TextFontHeight;
if(FirstX <= LastColumn && FirstY <= LastLine)
{
UBYTE Char;
ObtainSemaphore(RasterSemaphore);
Char = Raster[FirstY * RasterWidth + FirstX];
ReleaseSemaphore(RasterSemaphore);
if(Char)
{
SerWrite(&Char,1);
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
switch(Config -> TerminalConfig -> SendCR)
{
case CR_ASCR:
SerWrite("\r",1);
break;
case CR_ASCRLF:
SerWrite("\r\n",2);
break;
}
}
}
}
return(TRUE);
}
if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
{
WORD DeltaX,DeltaY;
ObtainTerminal();
DeltaX = MouseX / TextFontWidth - CursorX;
DeltaY = MouseY / TextFontHeight - CursorY;
ReleaseTerminal();
if(DeltaX || DeltaY)
{
if(DeltaX > 0)
{
DeltaX++;
while(DeltaX--)
SerWrite("\33[C",3);
}
if(DeltaX < 0)
{
while(DeltaX++)
SerWrite("\33[D",3);
}
if(DeltaY > 0)
{
DeltaY++;
while(DeltaY--)
SerWrite("\33[B",3);
}
if(DeltaY < 0)
{
while(DeltaY++)
SerWrite("\33[A",3);
}
}
return(TRUE);
}
ReportMouse(TRUE,Window);
if(!FirstClick)
{
ULONG CurrentSecs,CurrentMicros;
CurrentTime(&CurrentSecs,&CurrentMicros);
FirstClick = TRUE;
if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
{
MarkWord(ClickX,ClickY);
return(TRUE);
}
else
{
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
}
}
else
{
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
}
if(Marking)
{
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
MoveMarker(MouseX,MouseY);
else
{
DropMarker();
CurrentTime(&ClickSecs,&ClickMicros);
FirstClick = FALSE;
ClickX = MouseX;
ClickY = MouseY;
ReportMouse(TRUE,Window);
}
}
}
}
break;
}
}
/* Now for general information. */
switch(IClass)
{
case IDCMP_RAWKEY:
/* This looks like a raw, or better, now cooked key. */
if(Len)
{
switch(CharType[Char])
{
case CHAR_HELP:
GuideDisplay(CONTEXT_MAIN);
Len = 0;
break;
case CHAR_CURSOR:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
/* If in cursor key applications mode,
* send the corresponding string.
*/
if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
{
STATIC STRPTR CursorTable[4] =
{
"\033OA",
"\033OB",
"\033OC",
"\033OD"
};
SerWrite(CursorTable[Char - CUP],3);
}
else
{
WORD QualType;
/* Find the approriate qualifier. */
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
QualType = 1;
else
{
if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
QualType = 2;
else
{
if(Qualifier & IEQUALIFIER_CONTROL)
QualType = 3;
else
QualType = 0;
}
}
/* Send the corresponding string. */
SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
}
Len = 0;
break;
/* Any function key pressed? */
case CHAR_FUNCTION:
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
if(Qualifier & IEQUALIFIER_CONTROL)
SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
else
{
if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
else
{
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
else
SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
}
}
Len = 0;
break;
/* Anything else? */
default:
if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
{
RememberInputText("\r",1);
Len = 0;
RecordingLine = TRUE;
RememberResetInput();
RememberOutput = FALSE;
RememberInput = TRUE;
CheckItem(MEN_RECORD_LINE,TRUE);
}
if(Len == 1 && (Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
{
STATIC STRPTR ApplicationTable[20][2] =
{
"0", "\033Op",
"1", "\033Oq",
"2", "\033Or",
"3", "\033Os",
"4", "\033Ot",
"5", "\033Ou",
"6", "\033Ov",
"7", "\033Ow",
"8", "\033Ox",
"9", "\033Oy",
"-", "\033Om",
"+", "\033Ol", /* This should really be a comma */
".", "\033On",
"[", "\033OP",
"{", "\033OP",
"]", "\033OQ",
"}", "\033OQ",
"/", "\033OR",
"*", "\033OS",
"\r", "\033OM"
};
WORD i;
for(i = 0 ; i < 20 ; i++)
{
if(Char == ApplicationTable[i][0][0])
{
if(ClipInput)
{
CloseClip();
ClipInput = ClipXerox = ClipPrefix = FALSE;
}
SerWrite(ApplicationTable[i][1],strlen(ApplicationTable[i][1]));
Len = 0;
break;
}
}
}
break;
}
/* Any characters to send? */
if(Len)
SendInputTextBuffer(InputBuffer,Len,TRUE);
}
break;
/* A menu item was selected. */
case IDCMP_MENUPICK:
HandleMenu(Code,Qualifier);
break;
}
return(TRUE);
}
return(Result);
}
/* HandleLocalDialList(BYTE ClearIt):
*
* Invoke the local dialing list or clear it.
*/
STATIC VOID __regargs
HandleLocalDialList(BYTE ClearIt)
{
if(Menu)
{
struct MenuItem *DialItem;
if(DialItem = FindThisItem(Menu,FirstDialMenu))
{
if(Window)
ClearMenuStrip(Window);
if(StatusWindow)
ClearMenuStrip(StatusWindow);
if(FastWindow)
ClearMenuStrip(FastWindow);
do
DialItem -> Flags &= ~CHECKED;
while(DialItem = DialItem -> NextItem);
if(Window)
ResetMenuStrip(Window,Menu);
if(StatusWindow)
ResetMenuStrip(StatusWindow,Menu);
if(FastWindow)
ResetMenuStrip(FastWindow,Menu);
}
}
if(LocalDialList)
{
if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
{
FreeDialList(TRUE);
DialList = LocalDialList;
LocalDialList = NULL;
LocalCount = -1;
SetRedialMenu();
HandleMenuCode(MEN_REDIAL,NULL);
}
else
{
FreeList(LocalDialList);
FreeVecPooled(LocalDialList);
LocalDialList = NULL;
LocalCount = -1;
}
}
}
/* HandleMenuCode(ULONG Code,ULONG Qualifier):
*
* Handle each function associated with a menu code.
*/
VOID __regargs
HandleMenuCode(ULONG Code,ULONG Qualifier)
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH],
*DummyChar;
BYTE OldStatus = Status;
BPTR SomeFile;
APTR OldPtr;
struct MenuItem *Item;
switch(Code)
{
/* Save screen as IFF-ILBM file. */
case MEN_SAVE_AS_PICTURE:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
{
if(!SaveWindow(DummyBuffer,Window))
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save screen as ASCII file. */
case MEN_SAVE_AS_TEXT:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
{
LONG Error = 0;
if(GetFileSize(DummyBuffer))
{
switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
{
case 1: SomeFile = Open(DummyBuffer,MODE_NEWFILE);
break;
case 2: if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
{
if(Seek(SomeFile,0,OFFSET_END) == -1)
{
Close(SomeFile);
SomeFile = NULL;
}
}
break;
case 0: SomeFile = ~0;
break;
}
}
else
SomeFile = Open(DummyBuffer,MODE_NEWFILE);
if(SomeFile)
{
if(SomeFile != ~0)
{
LONG i,j;
UBYTE *Buffer;
for(i = 0 ; i < RasterHeight ; i++)
{
Buffer = &Raster[i * RasterWidth];
j = LastColumn;
while(j >= 0 && Buffer[j] == ' ')
j--;
if(j >= 0)
{
SetIoErr(0);
if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
{
Error = IoErr();
break;
}
}
SetIoErr(0);
if(FWrite(SomeFile,"\n",1,1) < 1)
{
Error = IoErr();
break;
}
}
Close(SomeFile);
AddProtection(DummyBuffer,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
}
}
else
Error = IoErr();
if(Error)
ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Print the screen (pure ASCII). */
case MEN_PRINT_SCREEN:
BlockWindows();
if(RasterEnabled)
PrintSomething(PRINT_SCREEN);
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
ReleaseWindows();
break;
/* Print the clipboard contents. */
case MEN_PRINT_CLIP:
BlockWindows();
PrintSomething(PRINT_CLIP);
ReleaseWindows();
break;
/* Open/close the terminal capture file. */
case MEN_CAPTURE_TO_FILE:
if(FileCapture)
CloseFileCapture();
else
OpenFileCapture();
break;
/* Start/terminate the printer
* capture.
*/
case MEN_CAPTURE_TO_PRINTER:
if(PrinterCapture)
ClosePrinterCapture(TRUE);
else
OpenPrinterCapture(FALSE);
break;
/* Iconify the program. */
case MEN_ICONIFY:
if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
{
if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
break;
}
DoIconify = TRUE;
break;
/* Say who we are. */
case MEN_ABOUT:
BlockWindows();
#ifdef DATAFEED
{
extern BPTR DataFeed;
if(DataFeed)
{
Close(DataFeed);
DataFeed = NULL;
}
if(FileRequest = GetFile(Window,"Select terminal test file","","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
{
if(GetFileSize(DummyBuffer))
{
if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
{
if(Kick30)
SetVBuf(DataFeed,NULL,2,8192);
}
}
FreeAslRequest(FileRequest);
}
}
#else
ShowAbout(FALSE);
#endif /* DATAFEED */
ReleaseWindows();
break;
/* Terminate the program. */
case MEN_QUIT:
if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
MainTerminated = TRUE;
else
{
STRPTR Buffer;
LONG OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
OldLen = Len;
if(Online)
Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
if(BufferChanged)
Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
if(ConfigChanged)
Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
if(PhonebookChanged)
Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
if(TranslationChanged)
Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
if(MacroChanged)
Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
if(CursorKeysChanged)
Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
if(FastMacrosChanged)
Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
if(HotkeysChanged)
Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
if(SpeechChanged)
Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
if(SoundChanged)
Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
BlockWindows();
OldPtr = ThisProcess -> pr_WindowPtr;
ThisProcess -> pr_WindowPtr = (APTR)Window;
if(OldLen != Len)
{
if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
{
SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
if(Online)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
strcat(Buffer,SharedBuffer);
}
if(BufferChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
strcat(Buffer,SharedBuffer);
}
if(ConfigChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(PhonebookChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
strcat(Buffer,SharedBuffer);
}
if(TranslationChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(MacroChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(CursorKeysChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(FastMacrosChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(HotkeysChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(SpeechChanged)
{
SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
strcat(Buffer,SharedBuffer);
}
if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
MainTerminated = TRUE;
FreeVecPooled(Buffer);
}
else
MainTerminated = TRUE;
}
else
MainTerminated = TRUE;
ThisProcess -> pr_WindowPtr = OldPtr;
ReleaseWindows();
}
break;
/* Feed the contents of the clipboard
* into the input stream.
*/
case MEN_PASTE:
if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
{
ClipInput = TRUE;
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
ClipXerox = TRUE;
}
else
ClipInput = FALSE;
break;
case MEN_COPY:
if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
ClipMarker(TRUE);
else
ClipMarker(FALSE);
break;
case MEN_CLEAR:
DropMarker();
break;
/* Execute an AmigaDOS command. */
case MEN_EXECUTE_DOS_COMMAND:
BlockWindows();
/* Enter the name of the command. */
if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
SendAmigaDOSCommand(AmigaDOSCommandBuffer);
ReleaseWindows();
break;
/* Execute an ARexx script command. */
case MEN_EXECUTE_REXX_COMMAND:
BlockWindows();
/* Get the rexx file name/program. */
if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
SendARexxCommand(ARexxCommandBuffer);
ReleaseWindows();
break;
/* Turn recording on/off. */
case MEN_RECORD:
if(GetItem(MEN_RECORD))
{
if(!Recording)
{
if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
{
RememberResetOutput();
RememberResetInput();
RememberOutput = TRUE;
Recording = TRUE;
RecordingLine = FALSE;
OnItem(MEN_RECORD_LINE);
}
}
}
else
{
if(Recording)
{
FinishRecord();
RememberOutput = FALSE;
RememberInput = FALSE;
Recording = FALSE;
RecordingLine = FALSE;
OffItem(MEN_RECORD_LINE);
}
}
break;
case MEN_RECORD_LINE:
if(Recording)
{
if(GetItem(MEN_RECORD))
{
if(!RecordingLine)
{
RecordingLine = TRUE;
RememberResetInput();
RememberOutput = FALSE;
RememberInput = TRUE;
}
}
else
{
if(RecordingLine)
{
RememberSpill();
RecordingLine = FALSE;
RememberOutput = TRUE;
RememberInput = FALSE;
}
}
}
break;
case MEN_DISABLE_TRAPS:
if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
{
ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
WatchTraps = TRUE;
else
WatchTraps = FALSE;
ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
}
break;
/* Edit the trap settings? */
case MEN_EDIT_TRAPS:
BlockWindows();
TrapPanel();
if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
{
if(WatchTraps)
Item -> Flags &= ~CHECKED;
else
Item -> Flags |= CHECKED;
}
ReleaseWindows();
break;
/* Set the name we will use to open the
* default console output window for
* AmigaDOS commands and ARexx scripts.
*/
case MEN_SET_CONSOLE:
BlockWindows();
if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
SetEnvDOS("TERMWINDOW",WindowName);
ReleaseWindows();
break;
/* Open the phonebook and dial the
* list of entries the user will select.
*/
case MEN_PHONEBOOK:
BlockWindows();
HandleLocalDialList(TRUE);
while(PhonePanel())
{
if(!DialPanel())
{
Status = OldStatus;
break;
}
Status = OldStatus;
}
SetRedialMenu();
ReleaseWindows();
break;
/* Redial those dial list entries which
* we were unable to connect.
*/
case MEN_REDIAL:
BlockWindows();
HandleLocalDialList(TRUE);
do
{
if(!DialPanel())
{
Status = OldStatus;
break;
}
Status = OldStatus;
}
while(PhonePanel());
SetRedialMenu();
ReleaseWindows();
break;
/* Dial a single number. */
case MEN_DIAL_NUMBER:
BlockWindows();
HandleLocalDialList(TRUE);
DummyBuffer[0] = 0;
if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DummyBuffer))
{
if(DummyBuffer[0])
{
struct List *LocalList;
if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
{
struct PhoneNode *DialNode;
LONG Len = strlen(DummyBuffer);
NewList(LocalList);
if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
{
DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
strcpy(DialNode -> VanillaNode . ln_Name,DummyBuffer);
AddTail(LocalList,&DialNode -> VanillaNode);
FreeDialList(TRUE);
DialList = LocalList;
DialPanel();
Status = OldStatus;
}
else
FreeVecPooled(LocalList);
}
}
}
SetRedialMenu();
ReleaseWindows();
break;
/* Send a break across the serial line. */
case MEN_SEND_BREAK:
SendBreak();
break;
/* Hang up the phone line. */
case MEN_HANG_UP:
BlockWindows();
if(DialMsg)
{
DialMsg -> rm_Result1 = RC_WARN;
DialMsg -> rm_Result2 = 0;
ReplyMsg(DialMsg);
DialMsg = NULL;
}
HangUp();
/* Remember online state. */
WasOnline = Online;
/* We are no longer online. */
Online = FALSE;
/* Clear the password. */
Password[0] = 0;
UserName[0] = 0;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
CurrentBBSNumber[0] = 0;
/* Reset time limit. */
LimitCount = -1;
/* Note the last action. */
if(CurrentPay)
{
/* Reset the text rendering styles, font, etc. in
* order to keep the following text from getting
* illegible.
*/
SoftReset();
/* Display how much we expect
* the user will have to pay for
* this call.
*/
ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
CurrentPay = 0;
}
else
LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
SoundPlay(SOUND_DISCONNECT);
ReleaseWindows();
/* Execute logoff macro. */
if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
SerialCommand(Config -> CommandConfig -> LogoffMacro);
/* Update the logfile. */
StopCall(FALSE);
/* Don't execute the logoff macro twice. */
WasOnline = FALSE;
ChosenEntry = NULL;
/* Enable the dialing functions. */
SetDialMenu(TRUE);
/* Previous configuration available? */
if(BackupConfig)
{
/* Remember old configuration. */
SaveConfig(Config,PrivateConfig);
/* Copy configuration. */
SaveConfig(BackupConfig,Config);
/* Set up new configuration. */
ConfigSetup();
/* Free old configuration. */
DeleteConfiguration(BackupConfig);
BackupConfig = NULL;
}
if(Config -> ModemConfig -> RedialAfterHangup)
{
if(DialList)
{
if(DialList -> lh_Head -> ln_Succ)
DoDial = DIAL_REDIAL;
}
}
break;
/* Wait a bit... */
case MEN_WAIT:
{
struct Window *ReqWindow;
struct EasyStruct Easy;
Easy . es_StructSize = sizeof(struct EasyStruct);
Easy . es_Flags = NULL;
Easy . es_Title = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
Easy . es_GadgetFormat = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
Easy . es_TextFormat = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
BlockWindows();
if(ReqWindow = BuildEasyRequest(Window,&Easy,NULL))
{
ULONG Signals;
BYTE Done = FALSE;
/* Don't echo serial output. */
Quiet = TRUE;
do
{
SerWrite(" \b",2);
HandleSerial();
StartTime(1,0);
Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
if(Signals & SIG_TIMER)
WaitIO(TimeRequest);
if(Signals & PORTMASK(ReqWindow -> UserPort))
{
if(!SysReqHandler(ReqWindow,NULL,FALSE))
{
Done = TRUE;
if(!CheckIO(TimeRequest))
AbortIO(TimeRequest);
WaitIO(TimeRequest);
}
}
}
while(!Done);
Quiet = FALSE;
FreeSysRequest(ReqWindow);
}
ReleaseWindows();
}
break;
/* Flush the serial buffers. */
case MEN_FLUSH_BUFFER:
ClearSerial();
RestartSerial(FALSE);
break;
/* Release the serial device for other
* applications.
*/
case MEN_RELEASE_DEVICE:
ReleaseSerial = TRUE;
break;
case MEN_UPLOAD_ASCII:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_ASCII,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_DOWNLOAD_ASCII:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_UPLOAD_TEXT:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
{
BinaryTransfer = FALSE;
StartXprSend(TRANSFER_TEXT,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
case MEN_DOWNLOAD_TEXT:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary))
{
BinaryTransfer = FALSE;
StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
BinaryTransfer = TRUE;
}
ResetProtocol();
ReleaseWindows();
break;
/* Edit and transfer a file. */
case MEN_EDIT_AND_UPLOAD_TEXT:
BlockWindows();
if(!Config -> PathConfig -> Editor[0])
GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
if(Config -> PathConfig -> Editor[0])
{
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
{
UBYTE CompoundName[512];
strcpy(CompoundName,Config -> PathConfig -> Editor);
strcat(CompoundName," \"");
strcat(CompoundName,DummyBuffer);
strcat(CompoundName,"\"");
SystemTags(CompoundName,
SYS_UserShell, TRUE,
TAG_DONE);
BumpWindow(Window);
FreeAslRequest(FileRequest);
if(GetFileSize(DummyBuffer))
{
BinaryTransfer = FALSE;
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
{
case 1: if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary))
SendTextFile(TRANSFER_ASCII,DummyBuffer);
ResetProtocol();
break;
case 2: if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary))
SendTextFile(TRANSFER_TEXT,DummyBuffer);
ResetProtocol();
break;
}
BinaryTransfer = TRUE;
}
}
}
ReleaseWindows();
break;
case MEN_UPLOAD_BINARY:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary))
{
BinaryTransfer = TRUE;
StartXprSend(TRANSFER_BINARY,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
/* Download some files. */
case MEN_DOWNLOAD_BINARY:
BlockWindows();
if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary))
{
BinaryTransfer = TRUE;
StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
}
ResetProtocol();
ReleaseWindows();
break;
/* Clear the contents of the scrollback
* buffer.
*/
case MEN_CLEAR_BUFFER:
if(Lines)
{
BlockWindows();
if(Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
{
FreeBuffer();
TerminateBuffer();
}
else
{
if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
{
FreeBuffer();
TerminateBuffer();
}
}
ReleaseWindows();
}
break;
/* Display the scrollback buffer.
* Notify the scrollback task or
* fire it off if approriate.
*/
case MEN_DISPLAY_BUFFER:
if(!LaunchBuffer())
{
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
ReleaseWindows();
}
break;
/* Close the buffer display. */
case MEN_CLOSE_BUFFER:
if(BufferTask)
{
Forbid();
Signal(BufferTask,SIG_KILL);
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
Permit();
}
break;
/* Is the buffer to be frozen? */
case MEN_FREEZE_BUFFER:
BufferFrozen ^= TRUE;
CheckItem(MEN_FREEZE_BUFFER,BufferFrozen);
Forbid();
ConOutputUpdate();
Permit();
break;
/* Load the buffer contents from a file. */
case MEN_OPEN_BUFFER:
BlockWindows();
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
{
if(GetFileSize(DummyBuffer))
{
if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
{
if(Lines)
{
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
{
case 1: FreeBuffer();
break;
case 2: break;
case 0: Close(SomeFile);
SomeFile = NULL;
break;
}
}
if(SomeFile)
{
LONG Len;
LineRead(NULL,NULL,NULL);
while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
StoreBuffer(DummyBuffer,Len);
Close(SomeFile);
BufferChanged = TRUE;
}
}
else
ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
}
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save the contents of the scrollback
* buffer to a file (line by line).
*/
case MEN_SAVE_BUFFER_AS:
BlockWindows();
if(!Lines || !BufferLines)
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
else
{
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
{
LONG Error = 0;
SomeFile = NULL;
/* If the file we are about
* to create already exists,
* ask the user whether we are
* to create, append or skip
* the file.
*/
if(GetFileSize(DummyBuffer))
{
switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
{
case 1: SomeFile = Open(DummyBuffer,MODE_NEWFILE);
break;
case 2: if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
{
if(Seek(SomeFile,0,OFFSET_END) == -1)
{
Close(SomeFile);
SomeFile = NULL;
}
}
break;
}
}
else
SomeFile = Open(DummyBuffer,MODE_NEWFILE);
if(SomeFile)
{
LONG i,Len;
/* Obtain the semaphore required
* to gain access to the line buffer
*/
ObtainSemaphore(BufferSemaphore);
for(i = 0 ; i < Lines ; i++)
{
Len = BufferLines[i][-1];
if(Len)
{
SetIoErr(0);
if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
{
Error = IoErr();
break;
}
}
SetIoErr(0);
if(FPrintf(SomeFile,"\n") < 1)
{
Error = IoErr();
break;
}
}
ReleaseSemaphore(BufferSemaphore);
Close(SomeFile);
AddProtection(DummyBuffer,FIBF_EXECUTE);
if(Config -> MiscConfig -> CreateIcons)
AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
BufferChanged = FALSE;
}
else
Error = IoErr();
if(Error)
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
}
ReleaseWindows();
break;
/* Simply clear the screen and move the
* cursor to its home position.
*/
case MEN_CLEAR_SCREEN:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorClearConsole(XEM_IO);
else
{
DropMarker();
ConBypass("\033[2J\033[H",-1);
}
break;
/* Reset the current text rendering font. */
case MEN_RESET_FONT:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetCharset(XEM_IO);
else
{
DropMarker();
CurrentFont = TextFont;
SetFont(RPort,CurrentFont);
ConOutputUpdate();
}
break;
/* Reset the display styles and restore
* the colours.
*/
case MEN_RESET_STYLES:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetTextStyles(XEM_IO);
else
{
DropMarker();
ConBypass("\033[0m",-1);
ObtainTerminal();
ClearCursor();
Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
FgPen = GetPenIndex(SafeTextPen);
BgPen = 0;
if(ReadAPen(RPort) != MappedPens[0][FgPen])
SetAPen(RPort,MappedPens[0][FgPen]);
if(ReadBPen(RPort) != MappedPens[0][BgPen])
SetBPen(RPort,MappedPens[0][BgPen]);
SetWrMsk(RPort,DepthMask);
ConFontScaleUpdate();
DrawCursor();
ReleaseTerminal();
}
break;
/* Reset the whole terminal. */
case MEN_RESET_TERMINAL:
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
XEmulatorResetConsole(XEM_IO);
else
{
FreeMarker();
ConBypass("\033c",-1);
}
break;
case MEN_SET_EMULATION:
BlockWindows();
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
{
OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
XEmulatorOptions(XEM_IO);
if(NewOptions)
{
SetEmulatorOptions(XEM_PREFS_SAVE);
NewOptions = FALSE;
}
OptionTitle = NULL;
}
else
EmulationPanel(Config,NULL);
ReleaseWindows();
break;
/* Set the serial preferences. */
case MEN_SERIAL:
BlockWindows();
if(SerialPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the modem preferences. */
case MEN_MODEM:
BlockWindows();
if(ModemPanel(Config,NULL))
{
FlowInit(TRUE);
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the screen preferences. */
case MEN_SCREEN:
BlockWindows();
if(ScreenPanel(Config,NULL))
{
if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
{
switch(Config -> ScreenConfig -> ColourMode)
{
case COLOUR_EIGHT:
CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
break;
case COLOUR_SIXTEEN:
CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
break;
case COLOUR_AMIGA:
CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
break;
case COLOUR_MONO:
CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
break;
}
}
ConfigSetup();
ConfigChanged = TRUE;
}
else
{
if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
{
switch(Config -> ScreenConfig -> ColourMode)
{
case COLOUR_EIGHT:
CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
break;
case COLOUR_SIXTEEN:
CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
break;
case COLOUR_AMIGA:
CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
break;
case COLOUR_MONO:
CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
break;
}
ConfigChanged = TRUE;
}
}
ReleaseWindows();
break;
/* Set the terminal preferences. */
case MEN_TERMINAL:
BlockWindows();
if(TerminalPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the clipboard preferences. */
case MEN_CLIPBOARD:
BlockWindows();
if(ClipPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the capture preferences. */
case MEN_CAPTURE:
BlockWindows();
if(CapturePanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the command preferences. */
case MEN_COMMANDS:
BlockWindows();
if(CommandPanel(Config,NULL))
ConfigChanged = TRUE;
ReleaseWindows();
break;
/* Set the miscellaneous preferences. */
case MEN_MISC:
BlockWindows();
if(MiscPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the path settings. */
case MEN_PATH:
BlockWindows();
if(PathPanel(Config,NULL))
ConfigChanged = TRUE;
ReleaseWindows();
break;
/* Set the file transfer options. */
case MEN_TRANSFER:
BlockWindows();
XprIO -> xpr_filename = NULL;
/* Set up the library options. */
if(XProtocolBase)
{
XPRCommandSelected = FALSE;
ClearSerial();
NewOptions = FALSE;
TransferBits = XProtocolSetup(XprIO);
RestartSerial(FALSE);
DeleteTransferPanel(TRUE);
/* Successful? */
if(!XPRCommandSelected)
{
if(!(TransferBits & XPRS_SUCCESS))
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
LastXprLibrary[0] = 0;
TransferBits = 0;
SetTransferMenu(FALSE);
}
else
SaveProtocolOpts();
}
}
ReleaseWindows();
break;
/* Set the file transfer procol settings. */
case MEN_TRANSFER_PROTOCOL:
BlockWindows();
if(LibPanel(Config,NULL))
{
ConfigSetup();
ConfigChanged = TRUE;
}
ReleaseWindows();
break;
/* Set the translation tables. */
case MEN_TRANSLATION:
BlockWindows();
TranslationChanged |= TranslationPanel();
/* Choose the right console write routine. */
ConOutputUpdate();
ReleaseWindows();
break;
/* Set the keyboard macros. */
case MEN_MACROS:
BlockWindows();
if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
{
XEmulatorMacroKeyFilter(XEM_IO,NULL);
MacroPanel(MacroKeys);
SetupXEM_MacroKeys(MacroKeys);
}
else
MacroPanel(MacroKeys);
ReleaseWindows();
break;
/* Set the cursor keys. */
case MEN_CURSORKEYS:
BlockWindows();
CursorPanel(CursorKeys);
ReleaseWindows();
break;
/* Set the fast macros. */
case MEN_FAST_MACROS:
BlockWindows();
FastMacroPanel();
ReleaseWindows();
break;
/* Set the hotkey preferences. */
case MEN_HOTKEYS:
BlockWindows();
if(HotkeyPanel(&Hotkeys))
{
if(!SetupCx())
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
ReleaseWindows();
break;
/* Set the speech preferences. */
case MEN_SPEECH:
BlockWindows();
SpeechPanel();
ReleaseWindows();
break;
/* Set the sound preferences. */
case MEN_SOUND:
BlockWindows();
if(SoundPanel(&SoundConfig))
SoundInit();
ReleaseWindows();
break;
/* Open the preferences settings. */
case MEN_OPEN_SETTINGS:
BlockWindows();
strcpy(DummyBuffer,LastConfig);
DummyChar = PathPart(DummyBuffer);
*DummyChar = 0;
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
{
if(ReadConfig(DummyBuffer,PrivateConfig))
{
SwapConfig(PrivateConfig,Config);
strcpy(DummyBuffer,LastConfig);
ConfigSetup();
ConfigChanged = FALSE;
}
else
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Save the terminal preferences. */
case MEN_SAVE_SETTINGS:
if(LastConfig[0])
{
BlockWindows();
if(!WriteConfig(LastConfig,Config))
ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
else
ConfigChanged = FALSE;
ReleaseWindows();
break;
}
/* Save the terminal preferences to a
* given file name.
*/
case MEN_SAVE_SETTINGS_AS:
BlockWindows();
strcpy(DummyBuffer,LastConfig);
DummyChar = PathPart(DummyBuffer);
*DummyChar = 0;
if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
{
if(WriteConfig(DummyBuffer,Config))
{
strcpy(LastConfig,DummyBuffer);
ConfigChanged = FALSE;
}
else
ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
FreeAslRequest(FileRequest);
}
ReleaseWindows();
break;
/* Show terminal information window. */
case MEN_STATUS_WINDOW:
if(InfoWindow)
CloseInfoWindow();
else
OpenInfoWindow();
break;
case MEN_REVIEW_WINDOW:
if(ReviewWindow)
DeleteReview();
else
CreateReview();
break;
/* Open the packet window if necessary, else
* just activate it.
*/
case MEN_PACKET_WINDOW:
CreatePacketWindow();
break;
/* Toggle the presence of the fast! macro panel. */
case MEN_FAST_MACROS_WINDOW:
if(FastWindow)
CloseFastWindow();
else
OpenFastWindow();
break;
/* Open the upload queue window. */
case MEN_UPLOAD_QUEUE_WINDOW:
CreateQueueProcess();
break;
default:if(Code >= DIAL_MENU_LIMIT)
{
LONG Index = Code - DIAL_MENU_LIMIT;
if(!LocalDialList && !Online)
{
if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
{
LONG i;
/* Clear previous list contents, we
* don't want to redial yet.
*/
for(i = 0 ; i < NumPhoneEntries ; i++)
Phonebook[i] -> Count = -1;
NewList(LocalDialList);
}
}
if(Phonebook[Index] -> Count == -1)
{
if(LocalDialList)
{
struct PhoneNode *NewNode;
/* Create a new node to be added to the dial list. */
if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
{
/* Take care of the name and the corresponding phone book entry. */
NewNode -> VanillaNode . ln_Name = NewNode -> LocalName;
NewNode -> Entry = Phonebook[Index];
Phonebook[Index] -> Count = ++LocalCount;
SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
/* Install back-link. */
NewNode -> Entry -> Node = NewNode;
AddTail(LocalDialList,&NewNode -> VanillaNode);
}
}
}
}
break;
}
}
/* HandleMenu(ULONG Code,ULONG Qualifier):
*
* Skip along the number of selected menu items and
* handle the associated functions.
*/
VOID __regargs
HandleMenu(ULONG Code,ULONG Qualifier)
{
struct MenuItem *MenuItem;
DisplayReopened = FALSE;
/* Check until the last menuitem has been
* processed.
*/
while(Code != MENUNULL)
{
/* Pick up the associated menu item. */
if(MenuItem = ItemAddress(Menu,Code))
{
HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
if(Apocalypse)
return;
if(DisplayReopened)
{
DisplayReopened = FALSE;
return;
}
Code = MenuItem -> NextSelect;
}
else
break;
}
HandleLocalDialList(FALSE);
}
/* HandleWorkbenchWindow():
*
* Handle input coming from the Workbench window.
*/
BYTE
HandleWorkbenchWindow()
{
struct FileInfoBlock *FileInfo;
struct AppMessage *AppMessage;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
struct FileTransferInfo *Info;
if(Info = AllocFileTransferInfo())
{
LONG FilesFound = 0,i;
BYTE Success = TRUE;
while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
{
if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
{
for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
{
if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
{
BPTR OldLock;
if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
{
BPTR FileLock;
if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(NameFromLock(FileLock,SharedBuffer,512))
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
{
FilesFound++;
if(Config -> MiscConfig -> TransferIcons)
{
BPTR InfoLock;
strcat(SharedBuffer,".info");
if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
{
if(Examine(InfoLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
UnLock(InfoLock);
}
}
}
}
}
}
UnLock(FileLock);
}
CurrentDir(OldLock);
}
}
}
}
ReplyMsg((struct Message *)AppMessage);
}
if(FilesFound)
{
SortFileTransferInfo(Info);
BlockWindows();
switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
{
case 1: BinaryTransfer = TRUE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_BINARY,TRUE);
break;
case 2: BinaryTransfer = FALSE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_TEXT,TRUE);
break;
case 0: FreeFileTransferInfo(Info);
break;
}
ReleaseWindows();
}
}
FreeDosObject(DOS_FIB,FileInfo);
}
while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
ReplyMsg((struct Message *)AppMessage);
return(FALSE);
}
/* HandleIconify():
*
* Handle program iconification.
*/
VOID
HandleIconify()
{
BYTE Released = FALSE;
/* Set the wait mouse pointer... */
BlockWindows();
/* Open workbench.library. */
if(WorkbenchBase)
{
/* Open icon.library. */
if(IconBase)
{
struct DiskObject *Icon;
if(!(Icon = GetProgramIcon()))
Icon = GetDefDiskObject(WBTOOL);
/* Did we get an icon? */
if(Icon)
{
struct MsgPort *IconPort;
/* Reset the icon type. */
Icon -> do_Type = NULL;
/* Default icon position. */
Icon -> do_CurrentX = NO_ICON_POSITION;
Icon -> do_CurrentY = NO_ICON_POSITION;
/* Create the Workbench reply port. */
if(IconPort = CreateMsgPort())
{
struct AppIcon *AppIcon;
/* Add the application icon. */
if(AppIcon = AddAppIcon(0,0,TermIDString,IconPort,NULL,Icon,TAG_DONE))
{
struct AppMessage *AppMessage;
UBYTE *String,*Error;
ULONG SignalSet;
/* Reset the guardian. */
IconTerminated = FALSE;
/* Release the window. */
Released = TRUE;
ReleaseWindows();
WindowBox . Left = Window -> LeftEdge;
WindowBox . Top = Window -> TopEdge;
WindowBox . Width = Window -> Width;
WindowBox . Height = Window -> Height;
/* Close the display. full stop. */
if(DeleteDisplay())
{
/* Reset and release the serial driver. */
if(Config -> MiscConfig -> ReleaseDevice)
{
ClearSerial();
DeleteSerial();
}
/* Wait for double-click. */
IconLoop: while(!IconTerminated)
{
SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
if(SignalSet & PORTMASK(IconPort))
{
/* Pick up application messages. */
while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
{
/* Received a double-click? */
IconTerminated = TRUE;
ReplyMsg(AppMessage);
}
}
/* Wake up if ARexx command received. */
if(SignalSet & SIG_REXX)
while(HandleRexx());
if(SignalSet & SIGBREAKF_CTRL_F)
IconTerminated = TRUE;
}
/* Open the serial driver. */
if(Config -> MiscConfig -> ReleaseDevice)
{
if(Error = CreateSerial())
{
DeleteSerial();
switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
{
case 1: IconTerminated = FALSE;
goto IconLoop;
case 0: MainTerminated = TRUE;
}
}
else
{
if(SerialMessage)
{
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
SerialMessage = NULL;
}
}
}
if(CantQuit && MainTerminated)
MainTerminated = FALSE;
/* Create the display. */
if(!MainTerminated)
{
if(String = CreateDisplay(FALSE))
{
if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
{
ClearSerial();
DeleteSerial();
IconTerminated = FALSE;
goto IconLoop;
}
else
MainTerminated = FALSE;
}
else
{
BumpWindow(Window);
PubScreenStuff();
}
}
}
else
{
BlockWindows();
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
ReleaseWindows();
}
/* Remove the application icon. */
RemoveAppIcon(AppIcon);
/* Reply pending messages. */
while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
ReplyMsg(AppMessage);
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
DeleteMsgPort(IconPort);
}
else
MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
FreeDiskObject(Icon);
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
}
else
MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
if(!Released)
ReleaseWindows();
/* Finished! */
DoIconify = FALSE;
}
/* HandleOnlineCleanup():
*
* Perform offline cleanup tasks.
*/
VOID
HandleOnlineCleanup()
{
SoundPlay(SOUND_DISCONNECT);
StopCall(FALSE);
if(CurrentPay)
{
/* Reset the text rendering styles, font, etc. in
* order to keep the following text from getting
* illegible.
*/
SoftReset();
/* Display how much we expect
* the user will have to pay for
* this call.
*/
ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
CurrentPay = 0;
}
else
LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
SetDialMenu(TRUE);
/* Execute logoff macro. */
if(Config -> CommandConfig -> LogoffMacro[0])
SerialCommand(Config -> CommandConfig -> LogoffMacro);
/* Clear the password. */
Password[0] = 0;
UserName[0] = 0;
CurrentBBSName[0] = 0;
CurrentBBSComment[0] = 0;
CurrentBBSNumber[0] = 0;
WasOnline = FALSE;
ChosenEntry = NULL;
LimitCount = -1;
/* Previous configuration available? */
if(BackupConfig)
{
/* Remember old configuration. */
SaveConfig(Config,PrivateConfig);
/* Copy configuration. */
SaveConfig(BackupConfig,Config);
/* Set up new configuration. */
ConfigSetup();
/* Free old configuration. */
DeleteConfiguration(BackupConfig);
BackupConfig = NULL;
}
if(Config -> ModemConfig -> RedialAfterHangup)
{
if(DialList)
{
if(DialList -> lh_Head -> ln_Succ)
DoDial = DIAL_REDIAL;
}
}
}
/* HandleFlowChange():
*
* Handle data flow scanner information.
*/
VOID
HandleFlowChange()
{
if(!Online && (FlowInfo . Voice || FlowInfo . Ring || FlowInfo . Connect))
{
if(FlowInfo . Voice)
{
UBYTE DateTimeBuffer[256];
FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
WakeUp(Window,SOUND_VOICE);
ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
}
if(FlowInfo . Ring)
{
UBYTE DateTimeBuffer[256];
FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
WakeUp(Window,SOUND_RING);
ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
}
if(FlowInfo . Connect)
{
WakeUp(Window,SOUND_CONNECT);
Online = TRUE;
BaudPending = FALSE;
SetDialMenu(FALSE);
}
}
/* Check if we are to prompt the user for
* ZModem upload type.
*/
if(UsesZModem && FlowInfo . ZModemUpload && XProtocolBase)
{
if(Config -> MiscConfig -> AutoUpload)
{
BlockWindows();
switch(UploadPanel())
{
case UPLOAD_TEXT:
BinaryTransfer = FALSE;
if(!StartXprSend(TRANSFER_TEXT,TRUE))
SerWrite(ZModemCancel,20);
break;
case UPLOAD_BINARY:
BinaryTransfer = TRUE;
if(!StartXprSend(TRANSFER_BINARY,TRUE))
SerWrite(ZModemCancel,20);
break;
case UPLOAD_ABORT:
SerWrite(ZModemCancel,20);
break;
case UPLOAD_BINARY_FROM_LIST:
StartUpload(UPLOAD_BINARY);
break;
case UPLOAD_TEXT_FROM_LIST:
StartUpload(UPLOAD_TEXT);
break;
}
ReleaseWindows();
}
}
FlowInit(TRUE);
}
/* HandleSerialReset():
*
* Handle serial device reset.
*/
VOID
HandleSerialReset()
{
ClearSerial();
DeleteSerial();
BlockWindows();
ReopenSerial();
ReleaseWindows();
}
/* HandleSerialRelease():
*
* Release the serial device driver, then reopen it again.
*/
VOID
HandleSerialRelease()
{
APTR OldPtr = ThisProcess -> pr_WindowPtr;
BYTE Continue,SerialClosed;
ThisProcess -> pr_WindowPtr = (APTR)Window;
/* This might happen if an ARexx user
* released the serial device and
* failed to reopen it.
*/
if(ReadPort)
SerialClosed = FALSE;
else
SerialClosed = TRUE;
BlockWindows();
/* Prevent catastrophes! */
if(Online && !SerialClosed)
{
if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
Continue = FALSE;
else
Continue = TRUE;
}
else
Continue = TRUE;
if(Continue)
{
if(SerialClosed)
ReopenSerial();
else
{
ClearSerial();
DeleteSerial();
if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
ReopenSerial();
else
MainTerminated = TRUE;
}
}
ReleaseSerial = FALSE;
ThisProcess -> pr_WindowPtr = OldPtr;
ReleaseWindows();
}
/* HandleExternalEmulation():
*
* Handle external emulation event.
*/
VOID
HandleExternalEmulation()
{
if(!XEmulatorSignal(XEM_IO,XEM_Signal))
{
CloseEmulator();
ResetDisplay = TRUE;
}
}
/* HandleSerialCheck():
*
* Handle routine checkup actions.
*/
BYTE
HandleSerialCheck()
{
/* Take a look at the carrier signal. */
if(Online && Config -> SerialConfig -> CheckCarrier && ReadPort && Status == STATUS_READY)
{
/* Query serial status. */
WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(WriteRequest);
/* Is the carrier detect signal
* still present?
*/
if(WriteRequest -> io_Status & CIAF_COMCD)
{
WasOnline = TRUE;
Online = FALSE;
}
}
/* Check online time limit. */
if(!LimitCount)
{
LimitCount = -1;
BlockWindows();
SendARexxCommand(LimitMacro);
ReleaseWindows();
}
/* Flush capture file contents to disk,
* this routine is executed each minute
* in order to store the captured data.
*/
if(!BufferFlushCount--)
{
BufferFlushCount = 60;
/* Flush the capture file. */
if(FileCapture)
BufferFlush(FileCapture);
}
return(FALSE);
}
/* HandleQueueMsg():
*
* Process the special message queue.
*/
BYTE
HandleQueueMsg()
{
struct DataMsg *Item;
if(Item = GetMsgItem(SpecialQueue))
{
struct FileTransferInfo *Info;
BYTE OldEcho;
switch(Item -> Type)
{
// Output data.
case DATAMSGTYPE_WRITE:
SerWrite(Item -> Data,Item -> Size);
break;
// Execute a command.
case DATAMSGTYPE_SERIALCOMMAND:
SerialCommand(Item -> Data);
break;
// Execute a command, but don't echo it.
case DATAMSGTYPE_SERIALCOMMANDNOECHO:
OldEcho = Config -> SerialConfig -> Duplex;
Config -> SerialConfig -> Duplex = DUPLEX_FULL;
SerialCommand(Item -> Data);
Config -> SerialConfig -> Duplex = OldEcho;
break;
// Output contents of clipboard
case DATAMSGTYPE_WRITECLIP:
if(!ClipInput)
{
if(!OpenClip(Item -> Size))
ClipInput = ClipXerox = TRUE;
else
ClipInput = ClipXerox = FALSE;
}
/* Are we reading input from the clipboard? */
if(ClipInput)
{
UBYTE InputBuffer[257];
WORD Len;
if((Len = GetClip(InputBuffer,256,FALSE)) < 0)
{
CloseClip();
ClipInput = FALSE;
if(ClipXerox)
{
if(Config -> ClipConfig -> InsertSuffix[0])
SerialCommand(Config -> ClipConfig -> InsertSuffix);
ClipXerox = FALSE;
}
ClipPrefix = FALSE;
}
else
{
if(!ClipPrefix && ClipXerox)
{
if(Config -> ClipConfig -> InsertPrefix[0])
SerialCommand(Config -> ClipConfig -> InsertPrefix);
ClipPrefix = TRUE;
}
if(Len > 0)
SendInputTextBuffer(InputBuffer,Len,FALSE);
}
}
break;
// Start an upload
case DATAMSGTYPE_UPLOAD:
if(Info = AllocFileTransferInfo())
{
struct FileInfoBlock *FileInfo;
LONG FilesFound = 0,Type = Item -> Size;
if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
{
BPTR FileLock;
struct List *List;
struct Node *Node,*Next;
APTR OldPtr = ThisProcess -> pr_WindowPtr;
ThisProcess -> pr_WindowPtr = (APTR)-1;
List = (struct List *)Item -> Data;
for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
{
if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
FilesFound++;
if(Config -> MiscConfig -> TransferIcons)
{
BPTR InfoLock;
strcpy(SharedBuffer,Node -> ln_Name);
strcat(SharedBuffer,".info");
if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
{
if(Examine(InfoLock,FileInfo))
{
if(FileInfo -> fib_DirEntryType < 0)
{
if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
FilesFound++;
}
}
UnLock(InfoLock);
}
}
Remove(Node);
FreeVecPooled(Node);
}
}
UnLock(FileLock);
}
}
ThisProcess -> pr_WindowPtr = OldPtr;
FreeDosObject(DOS_FIB,FileInfo);
}
DeleteMsgItem(Item);
Item = NULL;
if(FilesFound)
{
BlockWindows();
SortFileTransferInfo(Info);
switch(Type)
{
case UPLOAD_BINARY:
BinaryTransfer = TRUE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_BINARY,TRUE);
break;
case UPLOAD_TEXT:
BinaryTransfer = FALSE;
FileTransferInfo = Info;
StartXprSendFromList(TRANSFER_TEXT,TRUE);
break;
}
ReleaseWindows();
}
else
FreeFileTransferInfo(Info);
}
break;
// ARexx script execution finished.
case DATAMSGTYPE_COMMANDDONE:
if(CantQuit > 0)
CantQuit--;
BumpWindow(Window);
ReleaseWindows();
break;
// Call a menu item
case DATAMSGTYPE_MENU:
HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
break;
// Rendezvous with external process
case DATAMSGTYPE_RENDEZVOUS:
if(ReadRequest && WriteRequest)
{
// Abort serial I/O processing
ClearSerial();
BlockWindows();
// Return the message, caution, we're not ready yet
Forbid();
DeleteMsgItem(Item);
Item = NULL;
// Prepare to wait...
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
// Pick up the queue
RestartSerial(FALSE);
Permit();
ReleaseWindows();
}
break;
}
if(Item)
DeleteMsgItem(Item);
return(TRUE);
}
else
return(FALSE);
}
/* HandleOwnDevUnit():
*
* Deal with the OwnDevUnit signal notification.
*/
BYTE
HandleOwnDevUnit()
{
if(!Online || !ReadPort)
HandleSerialRelease();
return(FALSE);
}